home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Demos / OOFILE / Buildable, limited OOFILE / OOFILE headers / oofctrex.hpp < prev    next >
Encoding:
C/C++ Source or Header  |  1995-09-27  |  11.9 KB  |  398 lines  |  [TEXT/CWIE]

  1. #ifndef H_OOFctreeX
  2. #define H_OOFctreeX
  3.  
  4. // OOFILE c-tree Plus backend implementation
  5. // IMPLEMENTATION header
  6.  
  7. #include "oofctree.hpp"
  8. #include "oof2.hpp"
  9. #include "ooflist.hpp"
  10. #ifdef __CW55__
  11. // conflicts with defs in string.h if extern "C" these
  12.     #include "ctdecl.h"
  13.     #include "cterrc.h"
  14.     #include "ctaerr.h"
  15. #else
  16. extern "C" {
  17.     #include "ctdecl.h"
  18.     #include "cterrc.h"
  19.  
  20.     #ifdef _Windows
  21.         #define CTPERM
  22.         #include "ctstrc.h"
  23.         #include "ctgvar.h"
  24.     #else
  25.         #include "ctaerr.h"
  26.     #endif
  27. }
  28. #endif
  29.  
  30.  
  31. // locking macros
  32.  
  33. #define WITH_LOCK_WAIT  do {
  34.  
  35. #define IF_NON_LOCK_ERR      if (filErr && (filErr!=DLOK_ERR) && (filErr!=ITIM_ERR))
  36.  
  37. #define END_LOCK_WAIT(filErr)  \
  38.     if ((filErr==DLOK_ERR) || (filErr==ITIM_ERR)) {  \
  39.         LockCollisionWait();  \
  40.         continue; \
  41.     } \
  42. } while ((filErr==DLOK_ERR) || (filErr==ITIM_ERR));
  43.  
  44.  
  45. #ifdef _Macintosh
  46. const char kDirSeparator = ':';
  47. #else
  48.     #ifdef _Windows
  49. const char kDirSeparator = '\\';
  50.     #else
  51.         #ifdef _DOS
  52. const char kDirSeparator = '\\';
  53.         #else
  54. const char kDirSeparator = '/';
  55.         #endif
  56.     #endif
  57. #endif
  58.  
  59. class OOF_Context_ctree : public OOF_Context
  60. {
  61. public:
  62.     virtual ~OOF_Context_ctree();
  63.  
  64. protected:
  65.     OOF_Context_ctree(LONG off=0) : 
  66.                     mCurrLoadedRecOffset(off),
  67.                     mBuffer(0),
  68.                     mRecordState(off>0 ? eLoaded : eUnloaded),
  69.                     mBlobFieldBodies(0)
  70.                     {};
  71.     OOF_Context_ctree(const OOF_Context_ctree* rhs) : 
  72.                     mCurrLoadedRecOffset(rhs->mCurrLoadedRecOffset),
  73.                     mBuffer(rhs->mBuffer),
  74.                     mRecordState(rhs->mRecordState),
  75.                     mBlobFieldBodies(rhs->mBlobFieldBodies ? 
  76.                         new OOF_ExpandableLongArray(*(rhs->mBlobFieldBodies)) : 
  77.                         0)
  78.                     {};
  79.                     
  80.     void SetOffset(LONG);
  81. // data storage
  82.   enum ERecordState {eNew, eLoaded, eUnloaded};
  83.     LONG mCurrLoadedRecOffset;
  84.     char *mBuffer;    // owned
  85.     ERecordState mRecordState;
  86.     OOF_ExpandableLongArray* mBlobFieldBodies;
  87.     
  88.     friend class OOF_tableBackend_ctree;
  89. };
  90.  
  91.  
  92.  
  93.  
  94. class OOF_ctreeSelection;  // forward
  95.  
  96. class OOF_ctreeSelectionRep : public OOF_ExpandableLongArray, public OOF_mixRefCount {
  97. private:
  98. // construction
  99.     OOF_ctreeSelectionRep(unsigned long numSlots=0, unsigned int expandBySlots=10) :
  100.                                             OOF_ExpandableLongArray(0, numSlots, expandBySlots)
  101.                                             {};
  102.                             
  103.     unsigned long* ExposeArray();
  104.     void MarkAsUsed(unsigned long);
  105.  
  106.     friend class OOF_ctreeSelection;
  107. };
  108.  
  109.  
  110. class OOF_ctreeSelection {  
  111. // a Handle class for OOF_ctreeSelectionRep
  112.  
  113. // default constructor, or passing in zero items  skips allocating storage
  114. public:
  115.     enum selectionState {empty, oneRec, someRecs, allRecs};
  116.     enum {kDefExpansionChunk=10};
  117.     
  118.     OOF_ctreeSelection() ;
  119.     OOF_ctreeSelection(unsigned long numSlots);
  120.     OOF_ctreeSelection(const selectionState, unsigned long numSlots);
  121.     OOF_ctreeSelection(unsigned long numSlots, unsigned int expansionChunk);
  122.     OOF_ctreeSelection(const OOF_ctreeSelection&);  
  123.     ~OOF_ctreeSelection();
  124.     
  125.     unsigned long* allocSelection(unsigned long numSlots);
  126.     unsigned long* allocConsumedSelection(unsigned long numSlots);
  127.   void adopt(OOF_ctreeSelection&);
  128.   void copyContents(const OOF_ctreeSelection&);
  129.   
  130. // combinatorial operators
  131.   void difference_with(const OOF_ctreeSelection& rhs, OOF_tableBackend_ctree* caller);
  132.   void intersection_with(const OOF_ctreeSelection& rhs);
  133.   void union_with(const OOF_ctreeSelection& rhs);
  134.  
  135. // reflective operators  
  136.     selectionState state() const;
  137.     LONG oneRecOffset() const;
  138.     bool isEmpty() const;
  139.  
  140. // change state
  141.     void selectNone();
  142.     void selectOneRec(LONG);
  143.     void selectAll();
  144.     
  145. // access operators
  146.     unsigned long& operator[](unsigned long);
  147.     unsigned long& operator[](long);
  148.     unsigned long& operator()();
  149.     unsigned long value(unsigned long) const;
  150.     void append(unsigned long);
  151.     LONG appendNewRecord();
  152.   void deleteEntry(unsigned long itemIndex);
  153.   unsigned long& currentItem();  // same as operator() but easier to call internally
  154.  
  155.     // iterator protocol
  156.     void start();
  157.     bool more() const;
  158.     void next();
  159.     unsigned long count() const;
  160.  
  161. // boolean operators
  162.     bool isMember(unsigned long item) const;
  163.  
  164. // other protocol
  165.  
  166.     OOF_ctreeSelection& operator=(const OOF_ctreeSelection&);    
  167.  
  168. private:
  169.     void DropSelection();
  170.  
  171. // data storage
  172. private:
  173.     selectionState mState;
  174.     OOF_ctreeSelectionRep *mRep;    // owned
  175.     unsigned long mInternalIter;
  176.     LONG mCurrSingleRecOffset, mNextFakeNewRecOffset;
  177. }; 
  178.  
  179.  
  180. class OOF_ctreeFieldExtra {  // should really be a nested class
  181. private:
  182.     OOF_ctreeFieldExtra() :
  183.                                                 mKeyLength(0) 
  184.                                                 {};
  185. // data storage
  186.     VRLEN    mOffset, mLength, mKeyLength;
  187.     COUNT mIndexNo, mDODAfieldNo;
  188.  
  189.     friend class OOF_tableBackend_ctree;
  190. };
  191.  
  192.  
  193. // VERY simplistic class for now
  194. // later issues include recording masking only part of a field, this one assumes
  195. // each segment is the complete field
  196. class OOF_ctreeIndexSegList : public dbClass{  // should really be a nested class
  197. private:
  198.     OOF_ctreeIndexSegList(COUNT indexFileNo, const dbCompoundField* indexField);
  199.   virtual ~OOF_ctreeIndexSegList();
  200.  
  201. public:  
  202.   // data access
  203.   void appendFieldNo(fieldNumT);
  204.   fieldNumT fieldNo(unsigned short segmentNo) const;
  205.   bool  startsWith(fieldNumT) const;
  206.   bool  startsWith(unsigned long pairOfFieldNos) const;
  207.   COUNT indexFileNo() const;
  208.   const dbCompoundField* indexField() const;
  209.  
  210. private:
  211. // data storage
  212.     fieldNumT *mSegmentFieldNos;  // owned
  213.   const COUNT mIndexFileNo;
  214.   const dbCompoundField* mIndexField;
  215.   
  216.     friend class OOF_tableBackend_ctree;  // can create us
  217. };
  218.  
  219.  
  220. class OOF_ctreeIndexDictionary : public OOF_Dictionary {
  221. private:
  222.   OOF_ctreeIndexDictionary();
  223.   virtual ~OOF_ctreeIndexDictionary() {};
  224.   
  225.   // data access
  226.   COUNT  indexStartingWithField(fieldNumT) const;
  227.   const dbCompoundField* fieldMatchingPair(unsigned long) const;
  228.  
  229. friend class OOF_tableBackend_ctree;  // can create & use us
  230. };
  231.  
  232.  
  233. extern "C" {
  234. #ifdef NO_PROTOTYPE
  235. typedef LONG (ctDECL *ctComparativeKeySearch) (...);
  236. #else
  237. typedef LONG (ctDECL *ctComparativeKeySearch) (COUNT,pVOID,pVOID);
  238. #endif
  239. }
  240.  
  241.  
  242. class OOF_tableBackend_ctree : public OOF_tableBackend, private OOF_Context_ctree {
  243. private:
  244. // constructors
  245.     OOF_tableBackend_ctree(const OOF_Dictionary& tablesfields, const OOF_String& tableName, dbConnect_ctree* connection):
  246.                                                         OOF_tableBackend(tablesfields, tableName),
  247.                                                         mConnection(connection),
  248.                                                         mFieldBufMap(0),
  249.                                                         mRecordCache(0)
  250.                                                         {};
  251.     OOF_tableBackend_ctree(const OOF_tableBackend_ctree&, bool selectionNotCopied, const OOF_Dictionary& tablesFields);
  252.     void operator=(const OOF_tableBackend_ctree&) {assert(0);};
  253.     
  254.  public:
  255.     virtual ~OOF_tableBackend_ctree();
  256.  
  257.     virtual OOF_tableBackend* clone(bool selectionNotCopied, const OOF_Dictionary&) const;
  258.     virtual void buildSchema();
  259.     virtual void createTableInConnection(const dbConnect*);
  260.     virtual void openTableInConnection(const dbConnect*);
  261.     virtual unsigned int numIndexes() const;
  262.     virtual unsigned int numFiles() const;
  263.     
  264.     virtual void setBlobLength(fieldNumT, unsigned long len);
  265.     
  266. // public search functions
  267.     virtual bool gotoRecord(unsigned long);
  268.     virtual bool gotoRelativeRecord(unsigned long);
  269.     virtual void selectAll();
  270.     virtual void selectNone();
  271.     virtual bool search(const dbQueryClause* qClause);
  272.     virtual bool searchSelection(const dbQueryClause*);
  273.     virtual bool searchEqual(const dbField*, const char*, bool matchEntireKey=true);
  274.     virtual bool searchEqual(const dbField*, const VOID*);
  275.     virtual void difference_with(const OOF_tableBackend*);
  276.     virtual void intersection_with(const OOF_tableBackend*);  
  277.     virtual void invert();  
  278.     virtual void union_with(const OOF_tableBackend*);  
  279.     virtual bool loadRelatedContextJoiningFromTo(const dbField*, const dbField*);
  280.     
  281.     enum {kDataExtendSize=0, kIndexExtendSize=0};
  282.     enum {kCtreeKeySeqenceAddonLength=4};
  283.     
  284.  
  285. // recordwise access
  286.     virtual void start();
  287.     virtual void next();
  288.   virtual void prev();
  289.     virtual bool more() const;
  290.     virtual bool atFirst() const;
  291.     virtual bool atLast() const;
  292.  
  293.     virtual void sortBy(fieldNumT);
  294.     virtual unsigned long count() const;
  295.     virtual unsigned long countAll() const;
  296.  
  297. // data access
  298.     virtual void newRecord();
  299.     virtual void deleteRecord();
  300.     virtual void saveRecord();
  301.     virtual void unloadRecord();
  302.     virtual bool isRecordLoaded() const;
  303.     virtual unsigned long recordNumber() const;
  304.  
  305.     virtual void *getFieldWriteDest(fieldNumT);
  306.     virtual void *getFieldReadFrom(fieldNumT);
  307.     virtual void loadBlob(dbBLOB*);
  308.  
  309. // reflective operators
  310.     virtual unsigned long fieldDataLen(const dbField*) const;
  311.     virtual unsigned long blobPointerReferenceSize() const;
  312.     virtual long sequenceNumber() const;
  313.     
  314. // current record context management
  315.     virtual bool contextChangedFrom(const OOF_Context*) const;
  316.     virtual void updateContext(OOF_Context*) const;
  317.     virtual OOF_Context* createContext() const;
  318.     virtual void returnToContext(OOF_Context*);
  319.  
  320. protected:
  321.     virtual void CacheDirtyBuffer();
  322.  
  323. private:
  324.     COUNT MapFieldTypeToCtreeKeyType(const OOF_fieldTypes, bool caseSensitive) const;
  325.     COUNT MapFieldTypeToCtreeDODAType(const OOF_fieldTypes) const;
  326.     VRLEN BlobLenFromBuffer(const dbField*, const char* theirBuffer) const;
  327.     LONG BlobPosFromBuffer(const dbField* fld, const char* theirBuffer) const;
  328.     VRLEN BlobLenFromBuffer(fieldNumT, const char* theirBuffer) const;
  329.     LONG BlobPosFromBuffer(fieldNumT, const char* theirBuffer) const;
  330.     void SetBlobLenInBuffer(fieldNumT, VRLEN len, const char* theirBuffer) const;
  331.     void SetBlobPosInBuffer(fieldNumT, LONG pos, const char* theirBuffer) const;
  332.     void ResetBlobsFromCache(OOF_ExpandableLongArray*, const char* theirBuffer);
  333.     void LoadRecordAtOffset(LONG offset);
  334.     void CompleteLoadFromOffset(LONG offset);
  335.   void CompleteMoveToRecForAllRecs(COUNT err, const char* caller);
  336.     bool MaybeLoadRecordFromCache(LONG offset);
  337.   void SetISAMtoContext(const OOF_Context_ctree*);
  338.   void SaveContext(OOF_Context_ctree*);
  339.   void EnsureOurContextMatchesISAM();
  340.  
  341.     void AllocBuffer();
  342.     void AdoptBlobs();
  343.     void CompleteIIDX(const dbField *fld, IIDX& ix);
  344.     void BuildBackendtables();
  345.     DATOBJ* BuildDODA(UCOUNT& numDODAfields);
  346.     unsigned long PadFieldWidthForAlignment(const dbField* fld) const;
  347.     unsigned int FieldAlignsTo(const dbField*) const;
  348.     void ResetBlobs();
  349.     void BuildKey(COUNT keyIndexNo, char* target, const char* keyStr, COUNT keyStrLen, VRLEN keyLen) const;
  350.     void BuildKey(COUNT keyIndexNo, char* target, const char* keyStr, COUNT keyStrLen, VRLEN keyLen, LONG suffix) const;
  351.     void BuildKey(COUNT keyIndexNo, char* target, const VOID* binKey, VRLEN keyLen) const;
  352.     void BuildKey(COUNT keyIndexNo, char* target, const VOID* binKey, VRLEN keyLen, LONG suffix) const;
  353.  
  354.     bool SearchBinaryFieldToLiteral(const dbQueryBinary*);
  355.     bool SearchTrinaryFieldToLiterals(const dbQueryTrinary*);
  356.   bool SearchCombineSubclauses(const dbQueryBinaryCombo*);
  357.     void LockCollisionWait();
  358.  
  359.     bool SearchComparative(const dbField*, const char*, ctComparativeKeySearch, ctComparativeKeySearch, LONG possibleSuffix);
  360.     bool SearchComparative(const dbField*, const VOID*, ctComparativeKeySearch, ctComparativeKeySearch, LONG possibleSuffix);
  361.     bool SearchBetween(const dbField*, const char*, const char*);
  362.     bool SearchBetween(const dbField*, const VOID*, const VOID*);
  363.     
  364. // data storage
  365.     enum {kOverheadLeadingBytes = 2};
  366.     dbConnect_ctree* mConnection;
  367.     OOF_ctreeSelection mSelection;
  368.     OOF_ctreeFieldExtra *mFieldBufMap;  // owned semi-static member passed onto sub-collections
  369.     unsigned int* mFieldBufMapRefCount;  // owned semi-static member passed onto sub-collections
  370.     unsigned long mRecBufLen;
  371.     unsigned short mNumFiles, mNumIndexes, mOverheadLeadingBytes;
  372.     unsigned long mInternalIter;   // mainly used for All recs
  373.  
  374.  
  375.     COUNT mBlobFilNo, mISAMdatno, mSortIndexNo;  // c-tree file number handling
  376.     bool    mUnsorted;
  377.     OOF_ExpandableLongArray* mBlobFieldNums;  // owned
  378.     OOF_ExpandableLongArray* mRecordCache;  // owned (used as pointers)
  379.     IFIL  mIFIL;
  380.   OOF_ctreeIndexDictionary  mIndexDictionary;
  381.  
  382.     static COUNT sNextFileNo;
  383.     
  384.     static void ResetCtreeFileNoForStartOfConnection(COUNT nextFileNo);
  385.  
  386. public:
  387.     static COUNT sFileMode;
  388.  
  389.     friend void dbConnect_ctree::SetupConnection(const OOF_String& connectionName);
  390.     friend OOF_tableBackend *dbConnect_ctree::MakeTableBackend(const OOF_Dictionary& tablesfields, const OOF_String& tableName);
  391.     friend void dbTable::ContextChange();
  392. };
  393.  
  394.  
  395. // include inline definitions
  396. #include "oofctrex.inl"
  397.  
  398. #endif